#!/usr/bin/perl

use strict;
use lib "/net/cpp-group/caleb/new_node_stuff/my_perl_stuff";
use cwstats_fgu202 qw{ do_hyperGlogcalc};
use DBI;

#hsapiens_ensemblgene_GO_biol_process_map
#hsapiens_ensemblgene_GO_cell_location_map
#hsapiens_ensemblgene_GO_mol_function_map
#my $host='fgu200';
#my $user='caleb';
#my $database= 'ensembl_mart_19_3';
#my $password='';
#my $dbh_ens = DBI->connect("DBI:mysql:database=$database;host=$host",$user, $password,{'RaiseError' => 1});

#my $host='ensembldb.ensembl.org';
#my $user='anonymous';
#my $database= 'ensembl_mart_26_1';
#my $password='';
#my $dbh_ens = DBI->connect("DBI:mysql:database=$database;host=$host",$user, $password,{'RaiseError' => 1});

#my $host='fgu200';
#my $user='dqnguyen';
#my $database= 'ensembl_mart_25_1';
#my $password='';
#my $dbh_ens = DBI->connect("DBI:mysql:database=$database;host=$host",$user, $password,{'RaiseError' => 1});

#my $host='db';
#my $user='dqnguyen';
#my $database= 'ensembl_mart_31';
#my $password='';
#my $dbh_ens = DBI->connect("DBI:mysql:database=$database;host=$host",$user, $password,{'RaiseError' => 1});


my $host='db';
my $user='dqnguyen';
my $database= 'ensembl_mart_34';
my $password='';
my $dbh_ens = DBI->connect("DBI:mysql:database=$database;host=$host",$user, $password,{'RaiseError' => 1});


#my $host='ensembldb.ensembl.org';
#my $user='anonymous';
#my $database= 'ensembl_mart_27_1';
#my $password='';
#my $dbh_ens = DBI->connect("DBI:mysql:database=$database;host=$host",$user, $password,{'RaiseError' => 1});







#open(GOLM,">orth_GO_locmap_annotations")||die;
#open(GOBP,">orth_GO_bioproc_annotations")||die;
#open(GOFM,">orth_GO_funcmap_annotations")||die;

sub mk_GO_annots_file_for_genes 
{
	
	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time
	
	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift; #name forfile to put go lm info into
	my $gobp_fname = shift; #name forfile to put go bp info into
	my $gofm_fname = shift; #name forfile to put go fm info into
	
	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;
	
	
	foreach my $gene (@{$genes})
	{
	
		my $query1="select display_id,description,evidence_code from hsapiens_ensemblgene_GO_biol_process_map where gene_stable_id='$gene'";
		my $sth1=$dbh_ens->prepare($query1);
		$sth1->execute;
		#there may be several transcripts so I need to remove annotation redundancy
		my (@temp,@annot_bp);
		my $k=0;
		while ((@temp)=$sth1->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_bp[$k] = [@temp];
			$k++;
		}
		
		my $query2="select display_id,description,evidence_code from hsapiens_ensemblgene_GO_cell_location_map where gene_stable_id='$gene'";
		my $sth2=$dbh_ens->prepare($query2);
		$sth2->execute;
		#there may be several transcripts and I want to work with genes so I need to remove annotation redundancy
		my @annot_lm;
		$k=0;
		while ((@temp)=$sth2->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_lm[$k] = [@temp];
			$k++;
		}
		
		my $query3="select display_id,description,evidence_code from hsapiens_ensemblgene_GO_mol_function_map where gene_stable_id='$gene'";
		my $sth3=$dbh_ens->prepare($query3);
		$sth3->execute;
		my @annot_fm;
		$k=0;
		while ((@temp)=$sth3->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_fm[$k] = [@temp];
			$k++;
		}
		
		
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}
		
		foreach my $go_ent (@annot_bp)
		{
			print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
	
	
	} #closes foreach gene

} #closes sub mk_GO_annots_file_for_genes



sub mk_GO_annots_file_for_genes_ensmart34 
{

	## !! Mmusculus !!  Local query on ensembl_mart_34
	
	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift; #name forfile to put go lm info into
	my $gobp_fname = shift; #name forfile to put go bp info into
	my $gofm_fname = shift; #name forfile to put go fm info into
	
	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;
	
	
	foreach my $gene (@{$genes})
	{
		
		my $query1="SELECT glook_biol_process_id, description, olook_evidence_code FROM mmusculus_go_biol_process__go_biol_process__main WHERE gene_stable_id='$gene'";
		my $sth1=$dbh_ens->prepare($query1);
		$sth1->execute;
		#there may be several transcripts so I need to remove annotation redundancy
		my (@temp,@annot_bp);
		my $k=0;
		while ((@temp)=$sth1->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_bp[$k] = [@temp];
			$k++;
		}
		
		my $query2="SELECT glook_cell_location_id, description, olook_evidence_code FROM mmusculus_go_cell_location__go_cell_location__main where gene_stable_id='$gene'";
		my $sth2=$dbh_ens->prepare($query2);
		$sth2->execute;
		#there may be several transcripts and I want to work with genes so I need to remove annotation redundancy
		my @annot_lm;
		$k=0;
		while ((@temp)=$sth2->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_lm[$k] = [@temp];
			$k++;
		}
		
		my $query3="SELECT glook_mol_function_id, description, olook_evidence_code FROM  mmusculus_go_mol_function__go_mol_function__main  where gene_stable_id='$gene'";
		my $sth3=$dbh_ens->prepare($query3);
		$sth3->execute;
		my @annot_fm;
		$k=0;
		while ((@temp)=$sth3->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_fm[$k] = [@temp];
			$k++;
		}
		
		
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}
		
		foreach my $go_ent (@annot_bp)
		{
				print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
	} #closes foreach gene

} #closes sub mk_GO_annots_file_for_genes_ensmart34





sub mk_GO_annots_file_for_genes_ensmart31 
{

	## Local query on ensembl_mart_31
	
	
	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time
	
	
	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift; #name forfile to put go lm info into
	my $gobp_fname = shift; #name forfile to put go bp info into
	my $gofm_fname = shift; #name forfile to put go fm info into
	
	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;
	
	
	foreach my $gene (@{$genes})
	{
		
		my $query1="SELECT glook_biol_process_id, description, olook_evidence_code FROM hsapiens_go_biol_process__go_biol_process__main WHERE gene_stable_id='$gene'";
		my $sth1=$dbh_ens->prepare($query1);
		$sth1->execute;
		#there may be several transcripts so I need to remove annotation redundancy
		my (@temp,@annot_bp);
		my $k=0;
		while ((@temp)=$sth1->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_bp[$k] = [@temp];
			$k++;
		}
		
		my $query2="SELECT glook_cell_location_id, description, olook_evidence_code FROM hsapiens_go_cell_location__go_cell_location__main where gene_stable_id='$gene'";
		my $sth2=$dbh_ens->prepare($query2);
		$sth2->execute;
		#there may be several transcripts and I want to work with genes so I need to remove annotation redundancy
		my @annot_lm;
		$k=0;
		while ((@temp)=$sth2->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_lm[$k] = [@temp];
			$k++;
		}
		
		my $query3="SELECT glook_mol_function_id, description, olook_evidence_code FROM  hsapiens_go_mol_function__go_mol_function__main  where gene_stable_id='$gene'";
		my $sth3=$dbh_ens->prepare($query3);
		$sth3->execute;
		my @annot_fm;
		$k=0;
		while ((@temp)=$sth3->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_fm[$k] = [@temp];
			$k++;
		}
		
		
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}
		
		foreach my $go_ent (@annot_bp)
		{
			print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
	} #closes foreach gene

} #closes sub mk_GO_annots_file_for_genes_ensmart31







sub mk_GO_annots_file_for_genes_ensmart25 
{
	
	#Query local ensmart_25_1
	
	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time
	
	
	
	
	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift; #name forfile to put go lm info into
	my $gobp_fname = shift; #name forfile to put go bp info into
	my $gofm_fname = shift; #name forfile to put go fm info into
	
	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;
	
	
	foreach my $gene (@{$genes})
	{
		
		my $query1="SELECT glook_biol_process_id, description, olook_evidence_code FROM hsapiens_gene_ensembl__go_biol_process__look WHERE gene_stable_id='$gene'";
		my $sth1=$dbh_ens->prepare($query1);
		$sth1->execute;
		#there may be several transcripts so I need to remove annotation redundancy
		my (@temp,@annot_bp);
		my $k=0;
		while ((@temp)=$sth1->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_bp[$k] = [@temp];
			$k++;
		}
		
		my $query2="SELECT glook_cell_location_id, description, olook_evidence_code FROM hsapiens_gene_ensembl__go_cell_location__look where gene_stable_id='$gene'";
		my $sth2=$dbh_ens->prepare($query2);
		$sth2->execute;
		#there may be several transcripts and I want to work with genes so I need to remove annotation redundancy
		my @annot_lm;
		$k=0;
		while ((@temp)=$sth2->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_lm[$k] = [@temp];
			$k++;
		}
		
		my $query3="SELECT glook_mol_function_id, description, olook_evidence_code FROM  hsapiens_gene_ensembl__go_mol_function__look where gene_stable_id='$gene'";
		my $sth3=$dbh_ens->prepare($query3);
		$sth3->execute;
		my @annot_fm;
		$k=0;
		while ((@temp)=$sth3->fetchrow_array)
		{
			if ($temp[0] eq "")
			{
				next;
			}
			$annot_fm[$k] = [@temp];
			$k++;
		}
		
		
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}
		
		foreach my $go_ent (@annot_bp)
		{
			print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
	
	} #closes foreach gene

} #closes sub mk_GO_annots_file_for_genes_ensmart25_1




sub mk_GO_annots_file_for_genes_ensmart27 
{
	
	#Query remote ensmart_27_1
	
	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time
	
	
	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift; #name forfile to put go lm info into
	my $gobp_fname = shift; #name forfile to put go bp info into
	my $gofm_fname = shift; #name forfile to put go fm info into
	
	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;
	
	
	foreach my $gene (@{$genes})
	{
		
		my $query1="SELECT glook_biol_process_id, description, olook_evidence_code FROM mmusculus_gene_ensembl__go_biol_process__look WHERE gene_stable_id='$gene'";
		my $sth1=$dbh_ens->prepare($query1);
		$sth1->execute;
		#there may be several transcripts so I need to remove annotation redundancy
		my (@temp,@annot_bp);
		my $k=0;
		while ((@temp)=$sth1->fetchrow_array)
		{
		if ($temp[0] eq "")
		{
		next;
		}
		$annot_bp[$k] = [@temp];
		$k++;
		}
		
		my $query2="SELECT glook_cell_location_id, description, olook_evidence_code FROM mmusculus_gene_ensembl__go_cell_location__look where gene_stable_id='$gene'";
		my $sth2=$dbh_ens->prepare($query2);
		$sth2->execute;
		#there may be several transcripts and I want to work with genes so I need to remove annotation redundancy
		my @annot_lm;
		$k=0;
		while ((@temp)=$sth2->fetchrow_array)
		{
		if ($temp[0] eq "")
		{
		next;
		}
		$annot_lm[$k] = [@temp];
		$k++;
		}
		
		my $query3="SELECT glook_mol_function_id, description, olook_evidence_code FROM mmusculus_gene_ensembl__go_mol_function__look where gene_stable_id='$gene'";
		my $sth3=$dbh_ens->prepare($query3);
		$sth3->execute;
		my @annot_fm;
		$k=0;
		while ((@temp)=$sth3->fetchrow_array)
		{
		if ($temp[0] eq "")
		{
		next;
		}
		$annot_fm[$k] = [@temp];
		$k++;
		}
		
		
		for (my $l=0;$l<@annot_bp;$l++)
		{
		for (my $m=$l+1;$m<@annot_bp;$m++)
		{
		if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
		{
		splice(@annot_bp,$m,1);
		$m--;
		}
		}
		}
		
		foreach my $go_ent (@annot_bp){
		print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_lm;$l++)
		{
		for (my $m=$l+1;$m<@annot_lm;$m++)
		{
		if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
		{
		splice(@annot_lm,$m,1);
		$m--;
		}
		}
		}
		foreach my $go_ent (@annot_lm){
		print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
		for (my $l=0;$l<@annot_fm;$l++)
		{
		for (my $m=$l+1;$m<@annot_fm;$m++)
		{
		if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
		{
		splice(@annot_fm,$m,1);
		$m--;
		}
		}
		}
		foreach my $go_ent (@annot_fm){
		print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}
		
		
	} #closes foreach gene
	
} #closes sub mk_GO_annots_file_for_genes_ensmart27_1



sub mk_GO_annots_file_for_genes_ensmart27_largegenesets
{


	#this version downloads the three EnsMART go tables and then parses them, rather than 
	#doing a seperate query for each gene = faster
	
	#Query remote ensmart_27_1
	
	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time

	if (@_ != 6)
	{
		die "wrong num of args to sub mk_GO_annots_file_for_genes_ensmart27_largegenesets: expect 6 got: @_";
	}

	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift;	#name forfile to put go lm info into
	my $gobp_fname = shift;	#name forfile to put go bp info into
	my $gofm_fname = shift;	#name forfile to put go fm info into
	my $ens_org = shift;

	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;

	my (%all_bp,%all_fm,%all_lm,@data);	#all_xx{gene}->[[goid,des,evidence],[goid,des,evidence], ... ]
	my $query1="SELECT gene_stable_id, glook_biol_process_id, description, olook_evidence_code FROM $ens_org\_gene_ensembl__go_biol_process__look where glook_biol_process_id is not null";
	my $sth1=$dbh_ens->prepare($query1);
	$sth1->execute;
	while ((@data) = $sth1->fetchrow_array)
	{
		push @{$all_bp{$data[0]}},[@data[1..3]];
	}
	my $query2="SELECT gene_stable_id, glook_cell_location_id, description, olook_evidence_code FROM $ens_org\_gene_ensembl__go_cell_location__look where glook_cell_location_id is not null";
	my $sth2=$dbh_ens->prepare($query2);
	$sth2->execute;
	while ((@data) = $sth2->fetchrow_array)
	{
		push @{$all_lm{$data[0]}},[@data[1..3]];
	}
	my $query3="SELECT gene_stable_id, glook_mol_function_id, description, olook_evidence_code FROM $ens_org\_gene_ensembl__go_mol_function__look where glook_mol_function_id is not null";
	my $sth3=$dbh_ens->prepare($query3);
	$sth3->execute;
	while ((@data) = $sth3->fetchrow_array)
	{
		push @{$all_fm{$data[0]}},[@data[1..3]];
	}


	foreach my $gene (@{$genes})
	{

		my @annot_bp; #just being lazy and putting it into the old data struct forrest of code
		if (exists $all_bp{$gene})
		{
			foreach my $go (@{$all_bp{$gene}})
			{
				push @annot_bp,[@$go];
			}
		}


		my @annot_lm;
		if (exists $all_lm{$gene})
		{
			foreach my $go (@{$all_lm{$gene}})
			{
				push @annot_lm,[@{$go}];
			}
		}

		my @annot_fm;
		if (exists $all_fm{$gene})
		{
			foreach my $go (@{$all_fm{$gene}})
			{
				push @annot_fm,[@{$go}];}
		}

		#redundancy removal - couldn't this be done faster with a hash?
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}

		foreach my $go_ent (@annot_bp)
		{
			print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}


		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}


		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}


	} #closes foreach gene

} #closes sub mk_GO_annots_file_for_genes_ensmart27_largegenesets



sub mk_GO_annots_file_for_genes_ensmart19_largegenesets 
{


	#this version downloads the three EnsMART go tables and then parses them, rather than 
	#doing a seperate query for each gene = faster

	#Query remote ensmart_27_1

	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time

	if (@_ != 6)
	{
		die "wrong num of args to sub mk_GO_annots_file_for_genes_ensmart19_largegenesets: expect 6 got: @_";
	}

	my $genes = shift; #pointer to array of genes
	my $dbh_ens = shift; #database object
	my $golm_fname = shift;	#name forfile to put go lm info into
	my $gobp_fname = shift;	#name forfile to put go bp info into
	my $gofm_fname = shift;	#name forfile to put go fm info into
	my $ens_org = shift;

	open (GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;

	my (%all_bp,%all_fm,%all_lm,@data);	#all_xx{gene}->[[goid,des,evidence],[goid,des,evidence], ... ]
	my $query1="select gene_stable_id,display_id,description,evidence_code from $ens_org\_ensemblgene_GO_biol_process_map where display_id is not null";
	my $sth1=$dbh_ens->prepare($query1);
	$sth1->execute;
	while ((@data) = $sth1->fetchrow_array)
	{
		push @{$all_bp{$data[0]}},[@data[1..3]];
	}
	my $query2="select gene_stable_id,display_id,description,evidence_code from $ens_org\_ensemblgene_GO_cell_location_map where display_id is not null";
	my $sth2=$dbh_ens->prepare($query2);
	$sth2->execute;
	while ((@data) = $sth2->fetchrow_array)
	{
		push @{$all_lm{$data[0]}},[@data[1..3]];
	}
	my $query3="select gene_stable_id,display_id,description,evidence_code from $ens_org\_ensemblgene_GO_mol_function_map where display_id is not null";
	my $sth3=$dbh_ens->prepare($query3);
	$sth3->execute;
	while ((@data) = $sth3->fetchrow_array)
	{
		push @{$all_fm{$data[0]}},[@data[1..3]];
	}


	foreach my $gene (@{$genes})
	{


		my @annot_bp; #just being lazy and putting it into the old data struct forrest of code
		if (exists $all_bp{$gene})
		{
			foreach my $go (@{$all_bp{$gene}})
			{
				push @annot_bp,[@{$go}];
			}
		}



		my @annot_lm;
		if (exists $all_lm{$gene})
		{
			foreach my $go (@{$all_lm{$gene}})
			{
				push @annot_lm,[@{$go}];
			}
		}


		my @annot_fm;
		if (exists $all_fm{$gene})
		{
			foreach my $go (@{$all_fm{$gene}})
			{
				push @annot_fm,[@{$go}];}
		}

		#redundancy removal - couldn't this be done faster with a hash?
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}

		foreach my $go_ent (@annot_bp)
		{
			print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}


		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}


		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}


	} #closes foreach gene

} #closes sub mk_GO_annots_file_for_genes_ensmart27_largegenesets


sub get_GO_slims 
{
	#this func reads the names of the GO slim definitions in 2 hashes

	my $goslim = shift;	#this will hold the slim entries $goslim{$id}->{name|namespace|def|@parents}
	my $go_slim_all_ids = shift; #this will hold alt_id keys pointing to the main id value
	open(GOSLIM,"/net/cpp-group/caleb/new_node_stuff/GO/goslim_generic.obo")||die;
	my ($id,@parents) = ("");
	my $id_count=0;
	my $end_count=0;
	while (<GOSLIM>)
	{
		chomp;
		if (/^\[Term\]/)
		{
			$id=""; @parents=();
		}
		elsif (s/^id: GO://)
		{
			$id=$_;
			$go_slim_all_ids->{$id}=$id;
			$id_count++;
		}
		elsif (s/^name: //)
		{
			$goslim->{$id}->{name}=$_;
		}
		elsif (s/^alt_id: GO://)
		{
			$go_slim_all_ids->{$_}=$id;
		}
		elsif (s/^namespace: //)
		{
			$goslim->{$id}->{namespace}=$_;
		}
		elsif (s/^def: //)
		{
			$goslim->{$id}->{def}=$_;
		}
		elsif (s/^is_a: GO://)
		{
			push @parents,$_;
		}
		elsif ($_ eq "" && $id ne "")
		{
			@{$goslim->{$id}->{parents}} = @parents;
			$end_count++;
			$id="";
		}


	} #closes whle GOSLIM


} #closes sub get_GO_slims

#open(GOLM,">orth_GO_locmap_annotations")||die;
#open(GOBP,">orth_GO_bioproc_annotations")||die;
#open(GOFM,">orth_GO_funcmap_annotations")||die;


#_________________________________________________________________________________________
# 		push( @ {$gene2GO->{$gene_id}{$GO_type}} [GO_id, description, olook evidence_code])
#		for each gene, $loc_freqs->{$GO_id}++;
#		$loc_freqs->{all} = count of all genes with loc GO entry
#		$loc_freqs->{allslim} = count of all genes with loc GO slim entry
#		goid to goid2annot
#_________________________________________________________________________________________
sub read_GO_data
{

	my $gene2GO = shift; #hash pointer 
	my $go_slim_all_ids = shift; #hash pointer filled in by sub get_GO_slims

	my $loc_freqs = shift;
	my $bioproc_freqs = shift;
	my $funcmap_freqs = shift;
	my $goid2annot = shift;

	#for stats later, I need the total counts of entries for each type of GO annot

	my $golm_file = shift; #name of the GO loc map file produced by sub mk_GO_annots_file_for_genes
	my $gobp_file = shift; #name of the GO loc map file produced by sub mk_GO_annots_file_for_genes
	my $gofm_file = shift; #name of the GO loc map file produced by sub mk_GO_annots_file_for_genes

	open(GOLM,$golm_file)||die;
	open(GOBP,$gobp_file)||die;
	open(GOFM,$gofm_file)||die;

	my (%loc_seen,%bp_seen,%fm_seen,%go_slim_all_ids_locseen,%go_slim_all_ids_bpseen,%go_slim_all_ids_fmseen);



	while (<GOLM>)
	{
		chomp;
		my ($gene_id, $go_id, @line) = split(/ : /);
		#go_id, description, olook_evidence_code
		$go_id =~ s/GO://;
		push @{$gene2GO->{$gene_id}{loc}},$go_id;
		$loc_seen{$gene_id}=1; #count the number of genes that have a loc entry
		if (exists $go_slim_all_ids->{$go_id})
		{
			$go_slim_all_ids_locseen{$gene_id}=1;
		}
	}

	while (<GOBP>)
	{
		chomp;
		my @line = split(/ : /);
		$line[1] =~ s/GO://;
		push @{$gene2GO->{$line[0]}->{bioproc}},[$line[1],$line[2],$line[3]];
		$bp_seen{$line[0]}=1;
		if (exists $go_slim_all_ids->{$line[1]})
		{
			$go_slim_all_ids_bpseen{$line[0]}=1;
		}
	}

	while (<GOFM>)
	{
		chomp;
		my @line = split(/ : /);
		$line[1] =~ s/GO://;
		push @{$gene2GO->{$line[0]}->{funcmap}},[$line[1],$line[2],$line[3]];
		$fm_seen{$line[0]}=1;
		if (exists $go_slim_all_ids->{$line[1]})
		{
			$go_slim_all_ids_fmseen{$line[0]}=1;
		}
	}

	close(GOLM);
	close(GOBP);
	close(GOFM);

	
	#so lets get the total counts of orths with the 3 different types of GO annots
	my @temp = keys %loc_seen;
	$loc_freqs->{all} = @temp;
	@temp = keys %bp_seen;
	$bioproc_freqs->{all} = @temp;
	@temp = keys %fm_seen;
	$funcmap_freqs->{all} = @temp;
	@temp = keys %go_slim_all_ids_locseen;
	$loc_freqs->{allslim} = @temp;
	@temp = keys %go_slim_all_ids_bpseen;
	$bioproc_freqs->{allslim} = @temp;
	@temp = keys %go_slim_all_ids_fmseen;
	$funcmap_freqs->{allslim} = @temp;

	#ok, lets get the frequency of the terms for a start
	#my (%loc_freqs,%bioproc_freqs,%funcmap_freqs,%goid2annot);


	foreach my $gene (keys %{$gene2GO})
	{

		my %red_chk = (); #check for redundancy

		foreach my $go (@{$gene2GO->{$gene}->{loc}})
		{
			my $GO_id = $go->[0];
			#die "$go->[0] $go->[1] $go->[2] $go->[3]";
			$loc_freqs->{$GO_id}++;
			if (!exists $goid2annot->{$GO_id})
			{
				$goid2annot->{$GO_id} = $go->[1];
			}
			if (exists $red_chk{$GO_id})
			{
				die "l $GO_id seen already for $gene\n";
			}
			$red_chk{$GO_id}=1;
		}

		foreach my $go (@{$gene2GO->{$gene}->{bioproc}})
		{
			if (!exists $bioproc_freqs->{$go->[0]})
			{
				$bioproc_freqs->{$go->[0]}=1;
			}
			else
			{
				$bioproc_freqs->{$go->[0]}++;
			}
			if (!exists $goid2annot->{$go->[0]})
			{
				$goid2annot->{$go->[0]} = $go->[1];
			}
			if (exists $red_chk{$go->[0]})
			{
				die "b $go->[0] seen already for $gene\n";
			}
			$red_chk{$go->[0]}=1;
		}

		foreach my $go (@{$gene2GO->{$gene}->{funcmap}})
		{
			if (!exists $funcmap_freqs->{$go->[0]})
			{
				$funcmap_freqs->{$go->[0]}=1;
			}
			else
			{
				$funcmap_freqs->{$go->[0]}++;
			}
			if (!exists $goid2annot->{$go->[0]})
			{
				$goid2annot->{$go->[0]} = $go->[1];
			}
			if (exists $red_chk{$go->[0]})
			{
				die "f $go->[0] seen already for $gene\n";
			}
			$red_chk{$go->[0]}=1;
		}


	} #closes foreach GO orth entry



} #closes sub read_GO_data


sub analyse_GO_freqs
{	
	#what do we need?
	my $genes = shift; #pointer to array containing sample genes
	my $results = shift; #pointer to hash for results
	my $gene2GO = shift; #pointer to @gene2GO
	my $go_slim_all_ids = shift; #pointer to %go_slim_all_ids
	my $loc_freqs = shift; #pointer to %loc_freqs
	my $bioproc_freqs = shift; #pointer to %bioproc_freqs
	my $funcmap_freqs = shift; #pointer to %funcmap_freqs
	my $GOslimclass_totseen_loc = $loc_freqs->{allslim};
	my $GOslimclass_totseen_bp = $bioproc_freqs->{allslim};
	my $GOslimclass_totseen_fm = $funcmap_freqs->{allslim};
	my $GO_totseen_loc = $loc_freqs->{all};
	my $GO_totseen_bp = $bioproc_freqs->{all};
	my $GO_totseen_fm = $funcmap_freqs->{all};

	#die "GOslimclass_totseen_loc $GOslimclass_totseen_loc GOslimclass_totseen_bp $GOslimclass_totseen_bp GOslimclass_totseen_fm $GOslimclass_totseen_fm GO_totseen_loc $GO_totseen_loc GO_totseen_bp $GO_totseen_bp GO_totseen_fm $GO_totseen_fm";


	my $numgenes = @{$genes};
	$results->{numgenes} = $numgenes;

	#die "@{$genes}";
	#what do we need?
	#we need the frequency of all GO terms present

	my (%go_window,%go_slim_window); # $go_window->{loc|bp|fm}->{goid}=freq count
	foreach my $gene (@{$genes})
	{
		my ($have_loc,$have_bp,$have_fm,$have_loc_slim,$have_bp_slim,$have_fm_slim) =(0) x 6;
		#get the orth_index
		#my $oindex = $orth_ind->{$gene};
		foreach my $thisloc (@{$gene2GO->{$gene}->{loc}})
		{
			#die "thisloc $thisloc thisloc->[0] $thisloc->[0]";
			$have_loc=1;
			if (exists $go_slim_all_ids->{$thisloc->[0]})
			{
				$have_loc_slim=1;
			}
			if (!exists $go_window{loc}->{$thisloc->[0]})
			{
				$go_window{loc}->{$thisloc->[0]}=1;
			}
			else
			{
				$go_window{loc}->{$thisloc->[0]}++;
			}
		}
		foreach my $thisbp (@{$gene2GO->{$gene}->{bioproc}})
		{
			$have_bp=1;
			if (exists $go_slim_all_ids->{$thisbp->[0]})
			{
				$have_bp_slim=1;
			}
			if (!exists $go_window{bp}->{$thisbp->[0]})
			{
				$go_window{bp}->{$thisbp->[0]}=1;
			}
			else
			{
				$go_window{bp}->{$thisbp->[0]}++;
			}
		}
		foreach my $thisfm (@{$gene2GO->{$gene}->{funcmap}})
		{
			$have_fm=1;
			if (exists $go_slim_all_ids->{$thisfm->[0]})
			{
				$have_fm_slim=1;
			}
			if (!exists $go_window{fm}->{$thisfm->[0]})
			{
				$go_window{fm}->{$thisfm->[0]}=1;
			}
			else
			{
				$go_window{fm}->{$thisfm->[0]}++;
			}
		}

		#need to know how many genes have a GO entry type as this is the sample size
		if ($have_loc==1)
		{
			if (!exists $go_window{have_loc})
			{
				$go_window{have_loc}=1;
			}
			else
			{
				$go_window{have_loc}++;
			}
			if ($have_loc_slim==1)
			{
				if (!exists $go_window{have_loc_slim})
				{
					$go_window{have_loc_slim}=1;
				}
				else
				{
					$go_window{have_loc_slim}++;
				}
			}


		}
		if ($have_bp==1)
		{
			if (!exists $go_window{have_bp})
			{
				$go_window{have_bp}=1;
			}
			else
			{
				$go_window{have_bp}++;
			}
			if ($have_bp_slim==1)
			{
				if (!exists $go_window{have_bp_slim})
				{
					$go_window{have_bp_slim}=1;
				}
				else
				{
					$go_window{have_bp_slim}++;
				}
			}
		}
		if ($have_fm==1)
		{
			if (!exists $go_window{have_fm})
			{
				$go_window{have_fm}=1;
			}
			else
			{
				$go_window{have_fm}++;
			}
			if ($have_fm_slim==1)
			{
				if (!exists $go_window{have_fm_slim})
				{
					$go_window{have_fm_slim}=1;
				}
				else
				{
					$go_window{have_fm_slim}++;
				}
			}
		}



	} #closes foreach gene

	$results->{haveloc} = $go_window{have_loc};
	$results->{havebp} = $go_window{have_bp};
	$results->{havefm} = $go_window{have_fm};
	$results->{havelocslim} = $go_window{have_loc_slim};
	$results->{havebpslim} = $go_window{have_bp_slim};
	$results->{havefmslim} = $go_window{have_fm_slim};

   	#now lets select the go_slims
	foreach my $goid (keys %{$go_window{loc}})
	{
		if (exists $go_slim_all_ids->{$goid})
		{
			$go_slim_window{loc}->{$go_slim_all_ids->{$goid}} += $go_window{loc}->{$goid}; # += for GO syn ids
			#print KSWINDOWLOG "SLIM LOC GOID $goid $go_window{loc}->{$goid}\n";

		}
	}
	foreach my $goid (keys %{$go_window{bp}})
	{
		if (exists $go_slim_all_ids->{$goid})
		{
			$go_slim_window{bp}->{$go_slim_all_ids->{$goid}} += $go_window{bp}->{$goid};
			#print KSWINDOWLOG "SLIM BP GOID $goid $go_window{bp}->{$goid}\n";

		}
	}
	foreach my $goid (keys %{$go_window{fm}})
	{
		if (exists $go_slim_all_ids->{$goid})
		{
			$go_slim_window{fm}->{$go_slim_all_ids->{$goid}} += $go_window{fm}->{$goid};
			#print KSWINDOWLOG "SLIM FM GOID $goid $go_window{fm}->{$goid}\n";

		}
	}

	#ok, so now we've got the counts for both all and the slims, lets see what's significantly over represented in the slims
	foreach my $locid (keys %{$go_slim_window{loc}})
	{
		my $loc_cnt = $go_slim_window{loc}->{$locid};

		my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_loc,$loc_freqs->{$locid},$go_window{have_loc_slim},$loc_cnt);
		my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_loc,$loc_freqs->{$locid},$go_window{have_loc_slim},$loc_cnt);

		$results->{loc_results}->{$locid}->{tot_pop} = $GOslimclass_totseen_loc;
		$results->{loc_results}->{$locid}->{goid_pop} = $loc_freqs->{$locid};
		$results->{loc_results}->{$locid}->{samp_pop} = $go_window{have_loc_slim};
		$results->{loc_results}->{$locid}->{goid_samp} = $loc_cnt;
		$results->{loc_results}->{$locid}->{likelihoodG} = $likelihoodG;
		$results->{loc_results}->{$locid}->{likelihoodF} = $likelihoodF;


	}

	foreach my $bpid (keys %{$go_slim_window{bp}})
	{
		my $bp_cnt = $go_slim_window{bp}->{$bpid};

		my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_bp,$bioproc_freqs->{$bpid},$go_window{have_bp_slim},$bp_cnt);
		my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_bp,$bioproc_freqs->{$bpid},$go_window{have_bp_slim},$bp_cnt);

		$results->{bp_results}->{$bpid}->{tot_pop} = $GOslimclass_totseen_bp;
		$results->{bp_results}->{$bpid}->{goid_pop} = $bioproc_freqs->{$bpid};
		$results->{bp_results}->{$bpid}->{samp_pop} = $go_window{have_bp_slim};
		$results->{bp_results}->{$bpid}->{goid_samp} = $bp_cnt;
		$results->{bp_results}->{$bpid}->{likelihoodG} = $likelihoodG;
		$results->{bp_results}->{$bpid}->{likelihoodF} = $likelihoodF;


	}

	foreach my $fmid (keys %{$go_slim_window{fm}})
	{
		my $fm_cnt = $go_slim_window{fm}->{$fmid};

		my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_fm,$funcmap_freqs->{$fmid},$go_window{have_fm_slim},$fm_cnt);
		my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_fm,$funcmap_freqs->{$fmid},$go_window{have_fm_slim},$fm_cnt);

		$results->{fm_results}->{$fmid}->{tot_pop} = $GOslimclass_totseen_fm;
		$results->{fm_results}->{$fmid}->{goid_pop} = $funcmap_freqs->{$fmid};
		$results->{fm_results}->{$fmid}->{samp_pop} = $go_window{have_fm_slim};
		$results->{fm_results}->{$fmid}->{goid_samp} = $fm_cnt;
		$results->{fm_results}->{$fmid}->{likelihoodG} = $likelihoodG;
		$results->{fm_results}->{$fmid}->{likelihoodF} = $likelihoodF;


	}



} #closes sub do_go



sub analyse_allGO_freqs
{
	#what do we need?
	my $genes = shift; #pointer to array containing sample genes
	my $results = shift; #pointer to hash for results
	my $gene2GO = shift; #pointer to @gene2GO
	my $go_slim_all_ids = shift; #pointer to %go_slim_all_ids
	my $loc_freqs = shift; #pointer to %loc_freqs
	my $bioproc_freqs = shift; #pointer to %bioproc_freqs
	my $funcmap_freqs = shift; #pointer to %funcmap_freqs
	my $GOslimclass_totseen_loc = $loc_freqs->{allslim};
	my $GOslimclass_totseen_bp = $bioproc_freqs->{allslim};
	my $GOslimclass_totseen_fm = $funcmap_freqs->{allslim};
	my $GO_totseen_loc = $loc_freqs->{all};
	my $GO_totseen_bp = $bioproc_freqs->{all};
	my $GO_totseen_fm = $funcmap_freqs->{all};

	#die "GOslimclass_totseen_loc $GOslimclass_totseen_loc GOslimclass_totseen_bp $GOslimclass_totseen_bp GOslimclass_totseen_fm $GOslimclass_totseen_fm GO_totseen_loc $GO_totseen_loc GO_totseen_bp $GO_totseen_bp GO_totseen_fm $GO_totseen_fm";


	my $numgenes = @{$genes};
	$results->{numgenes} = $numgenes;

	#die "@{$genes}";
	#what do we need?
	#we need the frequency of all GO terms present

	my (%go_window,%go_slim_window); # $go_window->{loc|bp|fm}->{goid}=freq count
	foreach my $gene (@{$genes})
	{
		my ($have_loc,$have_bp,$have_fm,$have_loc_slim,$have_bp_slim,$have_fm_slim) =(0) x 6;;
		#get the orth_index
		#my $oindex = $orth_ind->{$gene};
		foreach my $thisloc (@{$gene2GO->{$gene}->{loc}})
		{
			#die "thisloc $thisloc thisloc->[0] $thisloc->[0]";
			$have_loc=1;
			if (exists $go_slim_all_ids->{$thisloc->[0]})
			{
				$have_loc_slim=1;
			}
			if (!exists $go_window{loc}->{$thisloc->[0]})
			{
				$go_window{loc}->{$thisloc->[0]}=1;
			}
			else
			{
				$go_window{loc}->{$thisloc->[0]}++;
			}
		}
		foreach my $thisbp (@{$gene2GO->{$gene}->{bioproc}})
		{
			$have_bp=1;
			if (exists $go_slim_all_ids->{$thisbp->[0]})
			{
				$have_bp_slim=1;
			}
			if (!exists $go_window{bp}->{$thisbp->[0]})
			{
				$go_window{bp}->{$thisbp->[0]}=1;
			}
			else
			{
				$go_window{bp}->{$thisbp->[0]}++;
			}
		}
		foreach my $thisfm (@{$gene2GO->{$gene}->{funcmap}})
		{
			$have_fm=1;
			if (exists $go_slim_all_ids->{$thisfm->[0]})
			{
				$have_fm_slim=1;
			}
			if (!exists $go_window{fm}->{$thisfm->[0]})
			{
				$go_window{fm}->{$thisfm->[0]}=1;
			}
			else
			{
				$go_window{fm}->{$thisfm->[0]}++;
			}
		}

   		#need to know how many genes have a GO entry type as this is the sample size
		if ($have_loc==1)
		{
			if (!exists $go_window{have_loc})
			{
				$go_window{have_loc}=1;
			}
			else
			{
				$go_window{have_loc}++;
			}
			if ($have_loc_slim==1)
			{
				if (!exists $go_window{have_loc_slim})
				{
					$go_window{have_loc_slim}=1;
				}
				else
				{
					$go_window{have_loc_slim}++;
				}
			}


		}
		if ($have_bp==1)
		{
			if (!exists $go_window{have_bp})
			{
				$go_window{have_bp}=1;
			}
			else
			{
				$go_window{have_bp}++;
			}
			if ($have_bp_slim==1)
			{
				if (!exists $go_window{have_bp_slim})
				{
					$go_window{have_bp_slim}=1;
				}
				else
				{
					$go_window{have_bp_slim}++;
				}
			}
		}
		if ($have_fm==1)
		{
			if (!exists $go_window{have_fm})
			{
				$go_window{have_fm}=1;
			}
			else
			{
				$go_window{have_fm}++;
			}
			if ($have_fm_slim==1)
			{
				if (!exists $go_window{have_fm_slim})
				{
					$go_window{have_fm_slim}=1;
				}
				else
				{
					$go_window{have_fm_slim}++;
				}
			}
		}



	} #closes foreach gene

	$results->{haveloc} = $go_window{have_loc};
	$results->{havebp} = $go_window{have_bp};
	$results->{havefm} = $go_window{have_fm};
	$results->{havelocslim} = $go_window{have_loc_slim};
	$results->{havebpslim} = $go_window{have_bp_slim};
	$results->{havefmslim} = $go_window{have_fm_slim};


	#ok, so now we've got the counts for both all and the slims, lets see what's significantly over represented in the slims
	foreach my $locid (keys %{$go_window{loc}})
	{
		my $loc_cnt = $go_window{loc}->{$locid};

	#die "$GO_totseen_loc,$loc_freqs->{$locid},$go_window{have_loc},$loc_cnt";
		my $likelihoodG = do_hyperGlogcalc_this_or_greater($GO_totseen_loc,$loc_freqs->{$locid},$go_window{have_loc},$loc_cnt);
		my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GO_totseen_loc,$loc_freqs->{$locid},$go_window{have_loc},$loc_cnt);

		$results->{loc_results}->{$locid}->{tot_pop} = $GO_totseen_loc;
		$results->{loc_results}->{$locid}->{goid_pop} = $loc_freqs->{$locid};
		$results->{loc_results}->{$locid}->{samp_pop} = $go_window{have_loc};
		$results->{loc_results}->{$locid}->{goid_samp} = $loc_cnt;
		$results->{loc_results}->{$locid}->{likelihoodG} = $likelihoodG;
		$results->{loc_results}->{$locid}->{likelihoodF} = $likelihoodF;


	}

	foreach my $bpid (keys %{$go_window{bp}})
	{
		my $bp_cnt = $go_window{bp}->{$bpid};

		#die "$GO_totseen_bp,$bioproc_freqs->{$bpid},$go_window{have_bp},$bp_cnt";
		my $likelihoodG = do_hyperGlogcalc_this_or_greater($GO_totseen_bp,$bioproc_freqs->{$bpid},$go_window{have_bp},$bp_cnt);
		my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GO_totseen_bp,$bioproc_freqs->{$bpid},$go_window{have_bp},$bp_cnt);

		$results->{bp_results}->{$bpid}->{tot_pop} = $GO_totseen_bp;
		$results->{bp_results}->{$bpid}->{goid_pop} = $bioproc_freqs->{$bpid};
		$results->{bp_results}->{$bpid}->{samp_pop} = $go_window{have_bp};
		$results->{bp_results}->{$bpid}->{goid_samp} = $bp_cnt;
		$results->{bp_results}->{$bpid}->{likelihoodG} = $likelihoodG;
		$results->{bp_results}->{$bpid}->{likelihoodF} = $likelihoodF;


	}

	foreach my $fmid (keys %{$go_window{fm}})
	{
		my $fm_cnt = $go_window{fm}->{$fmid};

		my $likelihoodG = do_hyperGlogcalc_this_or_greater($GO_totseen_fm,$funcmap_freqs->{$fmid},$go_window{have_fm},$fm_cnt);
		my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GO_totseen_fm,$funcmap_freqs->{$fmid},$go_window{have_fm},$fm_cnt);

		$results->{fm_results}->{$fmid}->{tot_pop} = $GO_totseen_fm;
		$results->{fm_results}->{$fmid}->{goid_pop} = $funcmap_freqs->{$fmid};
		$results->{fm_results}->{$fmid}->{samp_pop} = $go_window{have_fm};
		$results->{fm_results}->{$fmid}->{goid_samp} = $fm_cnt;
		$results->{fm_results}->{$fmid}->{likelihoodG} = $likelihoodG;
		$results->{fm_results}->{$fmid}->{likelihoodF} = $likelihoodF;


	}



} #closes sub analyse_allGO_freqs



#_________________________________________________________________________________________
# 		push( @ {$gene2GO->{$gene_id}{$GO_type}} [GO_id, description, olook evidence_code])
#		for each gene, $loc_freqs->{$GO_id}++;
#		$loc_freqs->{all} = count of all genes with loc GO entry
#		$loc_freqs->{allslim} = count of all genes with loc GO slim entry
#		goid to goid2annot
#_________________________________________________________________________________________
sub my_analyse_GO_freqs_inc_unseenGOs
{
	#what do we need?
	my $gene_ids = shift; #pointer to array containing sample gene_ids
	my $results = shift; #pointer to hash for results
	my $gene2GO = shift; #pointer to @gene2GO
	my $go_slim_all_ids = shift; #pointer to %go_slim_all_ids
	my $loc_freqs = shift; #pointer to %loc_freqs
	my $GOslimclass_totseen_loc = $loc_freqs->{allslim};
	my $GO_totseen_loc = $loc_freqs->{all};
	my $goslim = shift;	#pointer to %goslim filled in by sub get_GO_slims

	#die "GOslimclass_totseen_loc $GOslimclass_totseen_loc GOslimclass_totseen_bp $GOslimclass_totseen_bp GOslimclass_totseen_fm $GOslimclass_totseen_fm GO_totseen_loc $GO_totseen_loc GO_totseen_bp $GO_totseen_bp GO_totseen_fm $GO_totseen_fm";


	my $numgenes = @{$gene_ids};
	$results->{numgenes} = $numgenes;

	#die "@{$genes}";
	#what do we need?
	#we need the frequency of all GO terms present

	my (%go_window,%go_slim_window); # $go_window->{loc|bp|fm}->{goid}=freq count
	foreach my $gene_id (@{$gene_ids})
	{
		my ($have_loc,$have_loc_slim) =(0) x 2;
		#get the orth_index
		#my $oindex = $orth_ind->{$gene_id};
		foreach my $thisloc (@{$gene2GO->{$gene_id}->{loc}})
		{
			my $GO_id = $thisloc->[0];
			#die "thisloc $thisloc thisloc->[0] $GO_id";
			$have_loc=1;
			if (exists $go_slim_all_ids->{$GO_id})
			{
				$have_loc_slim=1;
			}
			$go_window{loc}{$GO_id}++;
		}

		#need to know how many gene_ids have a GO entry type as this is the sample size
		if ($have_loc)
		{
			$go_window{have_loc}++;
			if ($have_loc_slim)
			{
				++$go_window{have_loc_slim};
			}
		}
	}

	$results->{haveloc} = $go_window{have_loc};
	$results->{havelocslim} = $go_window{have_loc_slim};

	#now lets select the go_slims
	foreach my $GO_id (keys %{$go_window{loc}})
	{
		if (exists $go_slim_all_ids->{$GO_id})
		{
			$go_slim_window{loc}{$go_slim_all_ids->{$GO_id}} += $go_window{loc}->{$GO_id}; # += for GO syn ids
		}
	}

	#ok, so now we've got the counts for both all and the slims, lets see what's significantly over represented in the slims

	foreach my $this_go_slim (keys %{$go_slim_all_ids})
	{

		if ($this_go_slim ne $go_slim_all_ids->{$this_go_slim})
		{
			next;
		} #alt ids are repeats of superceding ids

		if ((!defined $loc_freqs->{$this_go_slim})&&(!defined $bioproc_freqs->{$this_go_slim})&&(!defined $funcmap_freqs->{$this_go_slim}))
		{
			warn "GOSLIM $this_go_slim $goslim->{$this_go_slim}->{name} $goslim->{$this_go_slim}->{namespace} not present in background - skipping\n";
			next;
		}

		#die $this_go_slim;
		#foreach my $locid (keys %{$go_slim_window{loc}})
		if ($goslim->{$this_go_slim}->{namespace} eq "component")
		{ #location
			my $loc_cnt = 0;
			if (defined $go_slim_window{loc}->{$this_go_slim})
			{
				$loc_cnt = $go_slim_window{loc}->{$this_go_slim};
			}

			my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_loc,$loc_freqs->{$this_go_slim},$go_window{have_loc_slim},$loc_cnt);
			my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_loc,$loc_freqs->{$this_go_slim},$go_window{have_loc_slim},$loc_cnt);

			$results->{loc_results}->{$this_go_slim}->{tot_pop} = $GOslimclass_totseen_loc;
			$results->{loc_results}->{$this_go_slim}->{goid_pop} = $loc_freqs->{$this_go_slim};
			$results->{loc_results}->{$this_go_slim}->{samp_pop} = $go_window{have_loc_slim};
			$results->{loc_results}->{$this_go_slim}->{goid_samp} = $loc_cnt;
			$results->{loc_results}->{$this_go_slim}->{likelihoodG} = $likelihoodG;
			$results->{loc_results}->{$this_go_slim}->{likelihoodF} = $likelihoodF;


		}

		#foreach my $bpid (keys %{$go_slim_window{bp}})
		elsif ($goslim->{$this_go_slim}->{namespace} eq "process")
		{ #biological process

		}

		#foreach my $fmid (keys %{$go_slim_window{fm}})
		elsif ($goslim->{$this_go_slim}->{namespace} eq "function")
		{ #function
		}

		else
		{
			die "no component/process/function assignment for GOSLIM id $this_go_slim\n";
		}


	} #closes foreach %go_slim_all_ids


} #closes sub do_go


sub analyse_GO_freqs_inc_unseenGOs
{
	#what do we need?
	my $genes = shift; #pointer to array containing sample genes
	my $results = shift; #pointer to hash for results
	my $gene2GO = shift; #pointer to @gene2GO
	my $go_slim_all_ids = shift; #pointer to %go_slim_all_ids
	my $loc_freqs = shift; #pointer to %loc_freqs
	my $bioproc_freqs = shift; #pointer to %bioproc_freqs
	my $funcmap_freqs = shift; #pointer to %funcmap_freqs
	my $GOslimclass_totseen_loc = $loc_freqs->{allslim};
	my $GOslimclass_totseen_bp = $bioproc_freqs->{allslim};
	my $GOslimclass_totseen_fm = $funcmap_freqs->{allslim};
	my $GO_totseen_loc = $loc_freqs->{all};
	my $GO_totseen_bp = $bioproc_freqs->{all};
	my $GO_totseen_fm = $funcmap_freqs->{all};
	my $goslim = shift;	#pointer to %goslim filled in by sub get_GO_slims

	#die "GOslimclass_totseen_loc $GOslimclass_totseen_loc GOslimclass_totseen_bp $GOslimclass_totseen_bp GOslimclass_totseen_fm $GOslimclass_totseen_fm GO_totseen_loc $GO_totseen_loc GO_totseen_bp $GO_totseen_bp GO_totseen_fm $GO_totseen_fm";


	my $numgenes = @{$genes};
	$results->{numgenes} = $numgenes;

	#die "@{$genes}";
	#what do we need?
	#we need the frequency of all GO terms present

	my (%go_window,%go_slim_window); # $go_window->{loc|bp|fm}->{goid}=freq count
	foreach my $gene (@{$genes})
	{
		my ($have_loc,$have_bp,$have_fm,$have_loc_slim,$have_bp_slim,$have_fm_slim) =(0) x 6;;
		#get the orth_index
		#my $oindex = $orth_ind->{$gene};
		foreach my $thisloc (@{$gene2GO->{$gene}->{loc}})
		{
			#die "thisloc $thisloc thisloc->[0] $thisloc->[0]";
			$have_loc=1;
			if (exists $go_slim_all_ids->{$thisloc->[0]})
			{
				$have_loc_slim=1;
			}
			if (!exists $go_window{loc}->{$thisloc->[0]})
			{
				$go_window{loc}->{$thisloc->[0]}=1;
			}
			else
			{
				$go_window{loc}->{$thisloc->[0]}++;
			}
		}
		foreach my $thisbp (@{$gene2GO->{$gene}->{bioproc}})
		{
			$have_bp=1;
			if (exists $go_slim_all_ids->{$thisbp->[0]})
			{
				$have_bp_slim=1;
			}
			if (!exists $go_window{bp}->{$thisbp->[0]})
			{
				$go_window{bp}->{$thisbp->[0]}=1;
			}
			else
			{
				$go_window{bp}->{$thisbp->[0]}++;
			}
		}
		foreach my $thisfm (@{$gene2GO->{$gene}->{funcmap}})
		{
			$have_fm=1;
			if (exists $go_slim_all_ids->{$thisfm->[0]})
			{
				$have_fm_slim=1;
			}
			if (!exists $go_window{fm}->{$thisfm->[0]})
			{
				$go_window{fm}->{$thisfm->[0]}=1;
			}
			else
			{
				$go_window{fm}->{$thisfm->[0]}++;
			}
		}


		#need to know how many genes have a GO entry type as this is the sample size
		if ($have_loc==1)
		{
			if (!exists $go_window{have_loc})
			{
				$go_window{have_loc}=1;
			}
			else
			{
				$go_window{have_loc}++;
			}
			if ($have_loc_slim==1)
			{
				if (!exists $go_window{have_loc_slim})
				{
					$go_window{have_loc_slim}=1;
				}
				else
				{
					$go_window{have_loc_slim}++;
				}
			}


		}
		if ($have_bp==1)
		{
			if (!exists $go_window{have_bp})
			{
				$go_window{have_bp}=1;
			}
			else
			{
				$go_window{have_bp}++;
			}
			if ($have_bp_slim==1)
			{
				if (!exists $go_window{have_bp_slim})
				{
					$go_window{have_bp_slim}=1;
				}
				else
				{
					$go_window{have_bp_slim}++;
				}
			}
		}
		if ($have_fm==1)
		{
			if (!exists $go_window{have_fm})
			{
				$go_window{have_fm}=1;
			}
			else
			{
				$go_window{have_fm}++;
			}
			if ($have_fm_slim==1)
			{
				if (!exists $go_window{have_fm_slim})
				{
					$go_window{have_fm_slim}=1;
				}
				else
				{
					$go_window{have_fm_slim}++;
				}
			}
		}



	} #closes foreach gene

	$results->{haveloc} = $go_window{have_loc};
	$results->{havebp} = $go_window{have_bp};
	$results->{havefm} = $go_window{have_fm};
	$results->{havelocslim} = $go_window{have_loc_slim};
	$results->{havebpslim} = $go_window{have_bp_slim};
	$results->{havefmslim} = $go_window{have_fm_slim};

	#now lets select the go_slims
	foreach my $goid (keys %{$go_window{loc}})
	{
		if (exists $go_slim_all_ids->{$goid})
		{
			$go_slim_window{loc}->{$go_slim_all_ids->{$goid}} += $go_window{loc}->{$goid}; # += for GO syn ids
			#print KSWINDOWLOG "SLIM LOC GOID $goid $go_window{loc}->{$goid}\n";

		}
	}
	foreach my $goid (keys %{$go_window{bp}})
	{
		if (exists $go_slim_all_ids->{$goid})
		{
			$go_slim_window{bp}->{$go_slim_all_ids->{$goid}} += $go_window{bp}->{$goid};
			#print KSWINDOWLOG "SLIM BP GOID $goid $go_window{bp}->{$goid}\n";

		}
	}
	foreach my $goid (keys %{$go_window{fm}})
	{
		if (exists $go_slim_all_ids->{$goid})
		{
			$go_slim_window{fm}->{$go_slim_all_ids->{$goid}} += $go_window{fm}->{$goid};	
			#print KSWINDOWLOG "SLIM FM GOID $goid $go_window{fm}->{$goid}\n";

		}
	}

	#ok, so now we've got the counts for both all and the slims, lets see what's significantly over represented in the slims

	foreach my $this_go_slim (keys %{$go_slim_all_ids})
	{

		if ($this_go_slim ne $go_slim_all_ids->{$this_go_slim})
		{
			next;
		} #alt ids are repeats of superceding ids

		if ((!defined $loc_freqs->{$this_go_slim})&&(!defined $bioproc_freqs->{$this_go_slim})&&(!defined $funcmap_freqs->{$this_go_slim}))
		{
			warn "GOSLIM $this_go_slim $goslim->{$this_go_slim}->{name} $goslim->{$this_go_slim}->{namespace} not present in background - skipping\n";
			next;
		}

		#die $this_go_slim;
		#foreach my $locid (keys %{$go_slim_window{loc}})
		if ($goslim->{$this_go_slim}->{namespace} eq "component")
		{ #location
			my $loc_cnt = 0;
			if (defined $go_slim_window{loc}->{$this_go_slim})
			{
				$loc_cnt = $go_slim_window{loc}->{$this_go_slim};
			}

			my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_loc,$loc_freqs->{$this_go_slim},$go_window{have_loc_slim},$loc_cnt);
			my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_loc,$loc_freqs->{$this_go_slim},$go_window{have_loc_slim},$loc_cnt);

			$results->{loc_results}->{$this_go_slim}->{tot_pop} = $GOslimclass_totseen_loc;
			$results->{loc_results}->{$this_go_slim}->{goid_pop} = $loc_freqs->{$this_go_slim};
			$results->{loc_results}->{$this_go_slim}->{samp_pop} = $go_window{have_loc_slim};
			$results->{loc_results}->{$this_go_slim}->{goid_samp} = $loc_cnt;
			$results->{loc_results}->{$this_go_slim}->{likelihoodG} = $likelihoodG;
			$results->{loc_results}->{$this_go_slim}->{likelihoodF} = $likelihoodF;


		}

		#foreach my $bpid (keys %{$go_slim_window{bp}})
		elsif ($goslim->{$this_go_slim}->{namespace} eq "process")
		{ #biological process
			my $bp_cnt = 0;
			if (defined $go_slim_window{bp}->{$this_go_slim})
			{
				$bp_cnt = $go_slim_window{bp}->{$this_go_slim};
			}

			my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_bp,$bioproc_freqs->{$this_go_slim},$go_window{have_bp_slim},$bp_cnt);
			my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_bp,$bioproc_freqs->{$this_go_slim},$go_window{have_bp_slim},$bp_cnt);

			$results->{bp_results}->{$this_go_slim}->{tot_pop} = $GOslimclass_totseen_bp;
			$results->{bp_results}->{$this_go_slim}->{goid_pop} = $bioproc_freqs->{$this_go_slim};
			$results->{bp_results}->{$this_go_slim}->{samp_pop} = $go_window{have_bp_slim};
			$results->{bp_results}->{$this_go_slim}->{goid_samp} = $bp_cnt;
			$results->{bp_results}->{$this_go_slim}->{likelihoodG} = $likelihoodG;
			$results->{bp_results}->{$this_go_slim}->{likelihoodF} = $likelihoodF;


		}

		#foreach my $fmid (keys %{$go_slim_window{fm}})
		elsif ($goslim->{$this_go_slim}->{namespace} eq "function")
		{ #function
			my $fm_cnt = 0;
			if (defined $go_slim_window{fm}->{$this_go_slim})
			{
				$fm_cnt = $go_slim_window{fm}->{$this_go_slim};
			}

			my $likelihoodG = do_hyperGlogcalc_this_or_greater($GOslimclass_totseen_fm,$funcmap_freqs->{$this_go_slim},$go_window{have_fm_slim},$fm_cnt);
			my $likelihoodF = do_hyperGlogcalc_this_or_fewer($GOslimclass_totseen_fm,$funcmap_freqs->{$this_go_slim},$go_window{have_fm_slim},$fm_cnt);

			$results->{fm_results}->{$this_go_slim}->{tot_pop} = $GOslimclass_totseen_fm;
			$results->{fm_results}->{$this_go_slim}->{goid_pop} = $funcmap_freqs->{$this_go_slim};
			$results->{fm_results}->{$this_go_slim}->{samp_pop} = $go_window{have_fm_slim};
			$results->{fm_results}->{$this_go_slim}->{goid_samp} = $fm_cnt;
			$results->{fm_results}->{$this_go_slim}->{likelihoodG} = $likelihoodG;
			$results->{fm_results}->{$this_go_slim}->{likelihoodF} = $likelihoodF;


		}

		else
		{
			die "no component/process/function assignment for GOSLIM id $this_go_slim\n";
		}


	} #closes foreach %go_slim_all_ids


} #closes sub do_go




sub mk_GO_annots_file_from_NCGIGOfile
{

	#this sub is for working with the toxoplasma GO terms from TIGR 
	#/net/cpp-group/caleb/new_node_stuff/toxoplasma/Neospora_TIGR_GI_NCGI.release_5/NCGI.GO.012904
	
	#note this sub doesn't return anything. For a given set of genes it grabs the 3 classes of GO annotations 
	#and puts them in seperate files. This is to save time re-reading from ensmart every time

	if (@_ != 3)
	{
		die "wrong num of args to sub mk_GO_annots_file_for_genes_ensmart27_largegenesets: expect 6 got: @_";
	}

	#my $genes = shift; #pointer to array of genes
	#my $dbh_ens = shift; #database object
	my $golm_fname = shift;	#name for file to put go lm info into
	my $gobp_fname = shift;	#name for file to put go bp info into
	my $gofm_fname = shift;	#name for file to put go fm info into
	#my $ens_org = shift;
	my $file = "/net/cpp-group/caleb/new_node_stuff/toxoplasma/Neospora_TIGR_GI_NCGI.release_5/NCGI.GO.012904";
	my @genes;

	open(GOLM,">$golm_fname")||die;
	open(GOBP,">$gobp_fname")||die;
	open(GOFM,">$gofm_fname")||die;

	my (%all_bp,%all_fm,%all_lm,@data);	#all_xx{gene}->[[goid,des,evidence],[goid,des,evidence], ... ]
	open(DATA,$file)||die;
	my $geneid;
	while (<DATA>)
	{
		chomp;
		if (s/^>//)
		{
			$geneid = $_;
			push @genes,$_;
		}
		elsif (s/^GO://)
		{
			my @line = split(/\t/);
			if (@line != 5)
			{
				die ">5elements ".join(":",@line)."\n";
			}
			#elsif($line[2] ne ""){ die "line[2] ($line[2])\n"; }

			if ($line[3] =~ "P")
			{
				push @{$all_bp{$geneid}},[$line[0],$line[1],""];
			}
			elsif ($line[3] =~ "F")
			{
				push @{$all_fm{$geneid}},[$line[0],$line[1],""];
			}
			elsif ($line[3] =~ "C")
			{
				push @{$all_lm{$geneid}},[$line[0],$line[1],""];
			}
			else
			{
				die "didn't recognise GO type in ".join(":",@line)."\n";
			}
		}


	} #closes while DATA


	foreach my $gene (@genes)
	{

		my @annot_bp; #just being lazy and putting it into the old data struct for rest of code
		if (exists $all_bp{$gene})
		{
			foreach my $go (@{$all_bp{$gene}})
			{
				push @annot_bp,[@{$go}];
			}
		}


		my @annot_lm;
		if (exists $all_lm{$gene})
		{
			foreach my $go (@{$all_lm{$gene}})
			{
				push @annot_lm,[@{$go}];
			}
		}

		my @annot_fm;
		if (exists $all_fm{$gene})
		{
			foreach my $go (@{$all_fm{$gene}})
			{
				push @annot_fm,[@{$go}];}
		}

		#redundancy removal - couldn't this be done faster with a hash?
		for (my $l=0;$l<@annot_bp;$l++)
		{
			for (my $m=$l+1;$m<@annot_bp;$m++)
			{
				if ($annot_bp[$l]->[0] eq $annot_bp[$m]->[0])
				{
					splice(@annot_bp,$m,1);
					$m--;
				}
			}
		}

		foreach my $go_ent (@annot_bp)
		{
			print GOBP "$gene : ".join(" : ",@{$go_ent})."\n";
		}


		for (my $l=0;$l<@annot_lm;$l++)
		{
			for (my $m=$l+1;$m<@annot_lm;$m++)
			{
				if ($annot_lm[$l]->[0] eq $annot_lm[$m]->[0])
				{
					splice(@annot_lm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_lm)
		{
			print GOLM "$gene : ".join(" : ",@{$go_ent})."\n";
		}


		for (my $l=0;$l<@annot_fm;$l++)
		{
			for (my $m=$l+1;$m<@annot_fm;$m++)
			{
				if ($annot_fm[$l]->[0] eq $annot_fm[$m]->[0])
				{
					splice(@annot_fm,$m,1);
					$m--;
				}
			}
		}
		foreach my $go_ent (@annot_fm)
		{
			print GOFM "$gene : ".join(" : ",@{$go_ent})."\n";
		}



	} #closes foreach gene


} #closes sub mk_GO_annots_file_for_genes_ensmart27_largegenesets



1;

